#include <assert.h>
#include <unistd.h>

#include <xmlsec/xmldsig.h>
#include <xmlsec/xmltree.h>

#include <libxml/parser.h>

#include "../common.h"

void printReferences(xmlSecDSigCtxPtr ds) {
  int i;
  xmlSecDSigReferenceCtxPtr r;
  xmlSecBufferPtr buf;

  for(i = 0; i < xmlSecPtrListGetSize(&ds->signedInfoReferences); i++) {
    r = xmlSecPtrListGetItem(&ds->signedInfoReferences, i);
    assert(r);
    buf = xmlSecDSigReferenceCtxGetPreDigestBuffer(r);
    assert(buf);
    fprintf(stderr, "signedinfo reference %d (%d):\n", i, buf->size);
    write(2, buf->data, buf->size);
    fprintf(stderr, "\n end signedinfo reference\n");
  }
}

int main(int argc, char **argv) {
  int i;

  libSetup();
  for(i = 1; i < argc; i++) {
    xmlDocPtr doc;
    xmlNodePtr sig, key;
    xmlSecDSigCtxPtr ctx;

    fprintf(stderr, "Processing %s\n", argv[i]);
    doc = xmlParseFile(argv[i]);
    sig = xmlSecFindChild(xmlDocGetRootElement(doc), xmlSecNodeSignature, xmlSecDSigNs);
    if(!sig) {
      fprintf(stderr, "No ds:Signature found in %s\n", argv[i]);
      continue;
    }
    key = xmlSecFindChild(sig, xmlSecNodeKeyInfo, xmlSecDSigNs);
    if(!key) {
      fprintf(stderr, "No ds:KeyInfo found in %s\n", argv[i]);
      continue;
    }
    ctx = xmlSecDSigCtxCreate(NULL);
    ctx->flags |= XMLSEC_DSIG_FLAGS_STORE_SIGNEDINFO_REFERENCES;
    ctx->signKey = xmlSecKeyCreate();
    extractKey(ctx->signKey, key);
    if(xmlSecDSigCtxVerify(ctx, sig))
      fprintf(stderr, "Verify failed on %s\n", argv[i]);
    else if(ctx->status != xmlSecDSigStatusSucceeded)
      fprintf(stderr, "Status %d\n", ctx->status);
    else
      fprintf(stderr, "Succeeded\n");
    printReferences(ctx);
  }
  return 0;
}

